﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;

namespace Kea
{
    internal abstract class KeyComparerDataPlan<T>
    {
        public KeyComparerDataPlan(KeyComparerDataPlan<T> moreSignificantKeyComparer) { MoreSignificantKeyComparer = moreSignificantKeyComparer; }
        public abstract void ReadKey(T tableReaderWriter);
        public abstract int Compare(int a, int b);
        protected KeyComparerDataPlan<T> MoreSignificantKeyComparer { get; private set; }
    }

    internal abstract class KeyComparerProvider<T>
    {
        public KeyComparerProvider(KeyComparerProvider<T> moreSignificantKeyComparer) { MoreSignificantKeyComparer = moreSignificantKeyComparer; }
        public abstract KeyComparerDataPlan<T> CreateProvider();
        protected KeyComparerProvider<T> MoreSignificantKeyComparer { get; private set; }
    }


    internal sealed class KeyComparerProvider<T, TKey> : KeyComparerProvider<T>
    {
        private readonly bool _isAscending;
        private Func<T, TKey> _keyReader;
        public KeyComparerProvider(KeyComparerProvider<T> moreSignificantKeyComparer, Func<T, TKey> keyReader, bool asc)
            : base(moreSignificantKeyComparer)
        {
            _isAscending = asc;
            _keyReader = keyReader;
        }
        public override KeyComparerDataPlan<T> CreateProvider()
        {
            KeyComparerDataPlan<T> mskc = null;
            if (MoreSignificantKeyComparer != null) mskc = MoreSignificantKeyComparer.CreateProvider();
            return new KeyComparerDataPlan<T, TKey>(mskc, _keyReader, _isAscending);
        }
    }





    internal sealed class KeyComparerDataPlan<T, TKey> : KeyComparerDataPlan<T>
    {
        private readonly IComparer<TKey> _comparer;
        private readonly bool _isAscending;
        private Func<T, TKey> _keyReader;
        public KeyComparerDataPlan(KeyComparerDataPlan<T> moreSignificantKeyComparer, Func<T, TKey> keyReader, bool asc)
            : base(moreSignificantKeyComparer)
        {
            _isAscending = asc;
            _comparer = Comparer<TKey>.Default;
            _keyReader = keyReader;
        }
        private readonly List<TKey> _keys = new List<TKey>();

        public override void ReadKey(T tableReaderWriter)
        {
            _keys.Add(_keyReader(tableReaderWriter));
            if (MoreSignificantKeyComparer != null) MoreSignificantKeyComparer.ReadKey(tableReaderWriter);
        }

        public override int Compare(int a, int b)
        {
            int c;
            if (MoreSignificantKeyComparer != null)
            {
                c = MoreSignificantKeyComparer.Compare(a, b);
                if (c != 0) return c;
            }
            c = _comparer.Compare(_keys[a], _keys[b]);
            return (_isAscending) ? c : 0 - c;
        }

        //        public override void ClearKeys()
        //      {
        //        _keys.Clear();
        //      if (MoreSignificantKeyComparer != null) MoreSignificantKeyComparer.ClearKeys();
        //}
    }

}
